package pessoas.presenter;

import pessoas.ordenacao.ComparadorDeTelefoneContatoDesc;
import pessoas.ordenacao.ComparadorDeTelefoneContatoCres;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.MaskFormatter;
import org.mdidesktoppane.MDIDeskTopPane;
import pessoas.CommandListaContatos.DesfazerCommandLista;
import pessoas.CommandListaContatos.EditarCommandLista;
import pessoas.CommandListaContatos.ExcluirCommandLista;
import pessoas.CommandListaContatos.NovoCommandLista;
import pessoas.CommandListaContatos.VisualizarCommandLista;
import pessoas.collection.Contatos;
import pessoas.interfaces.ICommandListaContatos;
import pessoas.interfaces.IObservadorContatos;
import pessoas.model.Contato;
import pessoas.model.Usuario;
import pessoas.ordenacao.ComparadorDeNomeContatoCres;
import pessoas.ordenacao.ComparadorDeNomeContatoDesc;
import pessoas.ordenacao.ComparadorDeOperaContatoCres;
import pessoas.ordenacao.ComparadorDeOperaContatoDesc;
import pessoas.ordenacao.ComparadorDeUfContatoCres;
import pessoas.ordenacao.ComparadorDeUfContatoDesc;
import pessoas.view.ListaContatosView;

public final class ListaContatosPresenter implements IObservadorContatos {

    private ListaContatosView view;
    private Contatos contatos;
    private ArrayList<Contato> aux;
    private MDIDeskTopPane desktop;
    private DefaultTableModel tm;
    private Usuario usuario;
    private ICommandListaContatos commandListaContatos;

    public ListaContatosPresenter(Usuario u, final Contatos contatos, MDIDeskTopPane desktop) {

        view = new ListaContatosView(null, true);
        this.contatos = contatos;
        this.aux = contatos.getContatos();
        this.desktop = desktop;
        this.usuario = u;
        view.getjCbOrdena().setSelected(true);

        tm = new DefaultTableModel(
                new Object[][]{},
                new String[]{"Nome", "Sobrenome", "Telefone", "Uf", "Operadora"}) {

                    @Override
                    public boolean isCellEditable(int row, int col) {
                        return false;
                    }
                };

        try {
            Contatos.getInstancia().cadastrarObservador(this);
            carregaContatosTabela(this.contatos);
        } catch (FileNotFoundException ex) {
            JOptionPane.showMessageDialog(view, ex);
        }

        view.getjCbOrdena().addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                if (view.getCheckOrdNome().isSelected()) {
                    ordenaNomeCres(evt);
                } else if (view.getCheckOrdTel().isSelected()) {
                    ordenaTelefoneCres(evt);
                } else if (view.getCheckOrdUf().isSelected()) {
                    ordenaUfCres(evt);
                } else if (view.getCheckOrdOper().isSelected()) {
                    ordenaOperCres(evt);
                }
                view.getjCbOrdenaDesc().setSelected(false);
            }
        });

        view.getjCbOrdenaDesc().addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                if (view.getCheckOrdNome().isSelected()) {
                    ordenaNomeDesc(evt);
                } else if (view.getCheckOrdTel().isSelected()) {
                    ordenaTelefoneDesc(evt);
                } else if (view.getCheckOrdUf().isSelected()) {
                    ordenaUfDesc(evt);
                } else if (view.getCheckOrdOper().isSelected()) {
                    ordenaOperDesc(evt);
                }
                view.getjCbOrdena().setSelected(false);
            }
        });

        view.getCheckOrdNome().addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {

                view.getCheckOrdTel().setSelected(false);
                view.getCheckOrdUf().setSelected(false);
                view.getCheckOrdOper().setSelected(false);

                if (view.getjCbOrdena().isSelected()) {
                    ordenaNomeCres(evt);
                } else if (view.getjCbOrdenaDesc().isSelected()) {
                    ordenaNomeDesc(evt);
                }
            }
        });

        view.getCheckOrdTel().addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {

                view.getCheckOrdNome().setSelected(false);
                view.getCheckOrdUf().setSelected(false);
                view.getCheckOrdOper().setSelected(false);

                if (view.getjCbOrdena().isSelected()) {
                    ordenaTelefoneCres(evt);
                } else if (view.getjCbOrdenaDesc().isSelected()) {
                    ordenaTelefoneDesc(evt);
                }
            }
        });

        view.getCheckOrdUf().addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {

                view.getCheckOrdNome().setSelected(false);
                view.getCheckOrdTel().setSelected(false);
                view.getCheckOrdOper().setSelected(false);

                if (view.getjCbOrdena().isSelected()) {
                    ordenaUfCres(evt);
                } else if (view.getjCbOrdenaDesc().isSelected()) {
                    ordenaUfDesc(evt);
                }
            }
        });

        view.getCheckOrdOper().addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {

                view.getCheckOrdNome().setSelected(false);
                view.getCheckOrdTel().setSelected(false);
                view.getCheckOrdUf().setSelected(false);

                if (view.getjCbOrdena().isSelected()) {
                    ordenaOperCres(evt);
                } else if (view.getjCbOrdenaDesc().isSelected()) {
                    ordenaOperDesc(evt);
                }
            }
        });

        view.getBtnVisualizar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                visualizar();
            }
        });

        view.getBtnPesquisar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    pesquisar();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(view, ex);
                }
            }
        });

        view.getCheckNome().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JFormattedTextField jftfTelefone = new JFormattedTextField();
                view.getTxtPesquisar().setFormatterFactory(jftfTelefone.getFormatterFactory());
                view.getTxtPesquisar().setText("");
                view.getCheckTelefone().setSelected(false);
            }
        });

        view.getCheckTelefone().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JFormattedTextField jftfTelefone = new JFormattedTextField(Mascara("(##)####-####"));
                view.getTxtPesquisar().setFormatterFactory(jftfTelefone.getFormatterFactory());
                view.getCheckNome().setSelected(false);
            }
        });

        view.getBtnNovo().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                novoContato();
            }
        });

        view.getBtnEditar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                editarContato();
            }
        });

        view.getBtnExcluir().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    excluirContato();
                } catch (FileNotFoundException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                } catch (IllegalAccessException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                } catch (InstantiationException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                } catch (ClassNotFoundException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            }
        });

        view.getBtnDesfazer().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    desfazerAcaoContato();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            }
        });

        view.getBtnFechar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                view.setVisible(false);
                view.dispose();
            }
        });

        view.setLocationRelativeTo(view);
        view.setVisible(true);
    }

    public MaskFormatter Mascara(String Mascara) {

        MaskFormatter F_Mascara = new MaskFormatter();
        try {
            F_Mascara.setMask(Mascara); //Atribui a mascara  
            F_Mascara.setPlaceholderCharacter(' '); //Caracter para preencimento   
        } catch (Exception excecao) {
            excecao.printStackTrace();
        }

        return F_Mascara;
    }

    public void desfazerAcaoContato() throws Exception {
        commandListaContatos = new DesfazerCommandLista(contatos);
        commandListaContatos.exercutar();
    }

    public void excluirContato() throws FileNotFoundException, IllegalAccessException, InstantiationException, ClassNotFoundException, IOException {
        this.contatos.setArrayListContato(aux);
        Contato c = null;
        commandListaContatos = new ExcluirCommandLista(this, contatos, usuario);
        commandListaContatos.exercutar();
    }

    public void visualizar() {
        this.contatos.setArrayListContato(aux);
        commandListaContatos = new VisualizarCommandLista(this, contatos, usuario);
        commandListaContatos.exercutar();

    }

    public void novoContato() {
        this.contatos.setArrayListContato(aux);
        commandListaContatos = new NovoCommandLista(contatos, usuario);
        commandListaContatos.exercutar();
    }

    public void editarContato() {
        this.contatos.setArrayListContato(aux);
        commandListaContatos = new EditarCommandLista(this,contatos, usuario);
        commandListaContatos.exercutar();
    }

    public void pesquisar() throws Exception, FileNotFoundException {
        try {
            this.contatos.setArrayListContato(aux);
            String palavra = view.getTxtPesquisar().getText();
            ArrayList<Contato> pesquisa = new ArrayList<Contato>();
            if (palavra.equals("")) {
                carregaTableModel(this.contatos.getContatos());
            } else {
                for (int i = 0; i < contatos.getContatos().size(); i++) {
                    if (view.getCheckNome().isSelected()) {
                        if (contatos.getContatos().get(i).getNome().contains(palavra)) {
                            pesquisa.add(contatos.getContatos().get(i));
                        }
                    } else if (view.getCheckTelefone().isSelected()) {
                        if (contatos.getContatos().get(i).getTelefone().contains(palavra)) {
                            pesquisa.add(contatos.getContatos().get(i));
                        }
                    } else {
                        throw new Exception("Selecione o modo de Pesquisa: (Nome/Telefone)");
                    }
                }
                contatos.gravarLog("<Pesquisa> do contato <<" + palavra + ">>,<<" + getHora() + ">>,<<" + getData()
                        + ">>,<<" + this.usuario.getNomeUsuario() + ">>.");
                contatos.setArrayListContato(pesquisa);
                carregaTableModel(pesquisa);
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
            contatos.gravarLog("Ocorreu a falha:" + ex.getMessage() + "ao realizar <Pesquisa> do contato <<" + view.getTxtPesquisar().getText() + ">>,<<" + getHora() + ">>,<<" + getData()
                    + ">>,<<" + this.usuario.getNomeUsuario() + ">>.");

        }
    }

    public void carregaContatosTabela(Contatos contatos) throws FileNotFoundException {
        this.contatos = contatos;
        tm.setNumRows(0);
        carregaTableModel(this.contatos.getContatos());
        this.view.getTabela().setModel(tm);
    }
//----------------------------------Ordenação--------------------------------------------

    private void ordenaNomeCres(ActionEvent evt) {
        if (view.getjCbOrdena().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeNomeContatoCres());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaNomeDesc(ActionEvent evt) {
        if (view.getjCbOrdenaDesc().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeNomeContatoDesc());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaTelefoneCres(ActionEvent evt) {
        if (view.getjCbOrdena().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeTelefoneContatoCres());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaTelefoneDesc(ActionEvent evt) {
        if (view.getjCbOrdenaDesc().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeTelefoneContatoDesc());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaUfCres(ActionEvent evt) {
        if (view.getjCbOrdena().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeUfContatoCres());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaUfDesc(ActionEvent evt) {
        if (view.getjCbOrdenaDesc().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeUfContatoDesc());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaOperCres(ActionEvent evt) {
        if (view.getjCbOrdena().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeOperaContatoCres());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }

    private void ordenaOperDesc(ActionEvent evt) {
        if (view.getjCbOrdenaDesc().isSelected()) {
            ArrayList<Contato> lista = new ArrayList<Contato>(contatos.getContatos());
            Collections.sort(lista, new ComparadorDeOperaContatoDesc());
            carregaTableModel(lista);
        } else {
            carregaTableModel(contatos.getContatos());
        }
    }
//------------------------------------Fim Ordenação-----------------------------------------------

    public void carregaTableModel(ArrayList<Contato> c) {
        tm.setNumRows(0);
        for (int i = 0; i < c.size(); i++) {
            String contato = c.get(i).toString();
            String linha[] = contato.split(",");
            tm.addRow(linha);
        }

    }

    public ListaContatosView getView() {
        return view;
    }

    public String getHora() {
        StringBuilder sb = new StringBuilder();
        GregorianCalendar d = new GregorianCalendar();
        sb.append(d.get(GregorianCalendar.HOUR_OF_DAY));
        sb.append(":");
        sb.append(d.get(GregorianCalendar.MINUTE));
        sb.append(":");
        sb.append(d.get(GregorianCalendar.SECOND));
        return sb.toString();
    }

    public String getData() {
        Calendar data = Calendar.getInstance();
        Date d = data.getTime();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        dateFormat.format(d);
        return d.toLocaleString().substring(0, 10);
    }

    @Override
    public void atualizar(Contatos contatos) {
        try {
            carregaContatosTabela(contatos);
        } catch (FileNotFoundException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    }
}
